namespace("lesp.abstract");

/**
 * Abstract song.
 */
lesp.abstract.Song = lesp.Target.extend({

  _baseUrl  : null,
  _document : null,
  _pageUrl  : null,
  _exact    : null,
  _name     : null,


  constructor : function(match)
  {
    this.base(["loaded", "notLoaded"]);

    this._pageUrl = match.href;
    if(this._pageUrl.indexOf(this._baseUrl) != 0)
    {
      this._pageUrl = this._baseUrl + this._pageUrl;
    }
    
    this._exact   = match.dist == 0;
    this._name    = match.name;

    GM_xmlhttpRequest({
      method  : "get",
      url     : this._pageUrl,
      onload  : this._onLoad.bind(this),
      onerror : this.notify.bind(this, "notLoaded")
    });
  },
  
  isExact : function()
  {
    return this._exact;
  },
  
  getName : function()
  {
    return this._name;
  },

  _onLoad : function(response)
  {
    this._document = jQuery(lesp.mangleHtml(response.responseText));
    this.notify("loaded");
  },

  getPageUrl : function()
  {
    return this._pageUrl;
  }

});

/**
 * Base manager.
 */
lesp.abstract.Manager = lesp.Target.extend({

  _track             : null,
  _searchUrlTemplate : null,
  _songUrlQuery      : null,


  constructor : function(artist, track)
  {
    this.base(["found", "failed", "loaded"]);

    this._track = track;

    GM_xmlhttpRequest({
      method  : "get",
      url     : this._searchUrlTemplate.format(encodeURIComponent(artist)),
      onload  : this._onLoad.bind(this),
      onerror : this.notify.bind(this, "failed")
    });
  },

  _onLoad : function(response)
  {
    // be overriden
  },

  getSongUrlQuery : function()
  {
    return this._songUrlQuery;
  }

});

/**
 * Abstract song renderer.
 */
lesp.abstract.Renderer = lesp.Target.extend({

  _manager : null,
  _song    : null,
  _title   : null,


  constructor : function(manager)
  {
    this.base(["completed", "failed"]);

    manager.attach("loaded", (function(target, song)
    {
      this._song = song;
      this.notify("completed");
    }).bind(this));
    manager.attach("failed", this.notify.bind(this, "failed"));
  },

  getTitle : function()
  {
    return this._title; 
  },

  _createMatchNotice : function()
  {
    if(this._song.isExact())
    {
      return "";  
    }
    
    return [
      "<p style='color:#bbb;font-size:10pt;text-align:center;'>",
      "No exact match is found. Best match is {0}.".format(this._song.getName()),
      "</p>"
    ].join("");
  },
  
  render : function()
  {
    // be overriden
  }

});


